package jupiter.messaging;

import java.util.Hashtable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.json.JSONException;
import org.json.JSONObject;


import javax.naming.InitialContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.mortbay.util.ajax.Continuation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jms.*;
import java.io.Serializable;


import jupiter.filters.UserFilter;
import jupiter.messaging.*;
import jupiter.util.Timey;
//this is the address book for a single application
public class ApplicationAddressBook {
	static private Hashtable<String, Domain> domain_hash = new Hashtable<String, Domain>();
	static private Hashtable<String, Domain> user_hash = new Hashtable<String, Domain>();
	
	static Logger logger = LoggerFactory.getLogger(ApplicationAddressBook.class);
	static private Hashtable<String, Continuation> continuation_hash = new Hashtable<String, Continuation>();
	static public Pattern pattern = Pattern.compile("https?://(?:www\\.)?([^/]*)([^#\\?]*)");
	
	public ApplicationAddressBook(){
	}
	
	
	static public void send(Serializable s){
		Timey t = new Timey();
		logger.warn("why is this being called");
		t.end("Publish");
	}
	
	static public String getDomainName(String url){
		String domain_name = "jabbify.com";
		Matcher matcher = pattern.matcher(url);
		boolean matchFound = matcher.find();
		if(matchFound){
			domain_name = matcher.group(1).toLowerCase();
		}else{
			domain_name = "file.file";
		}
		return domain_name;
	}
	
	static Domain getDomain(String domain_name){
		Domain domain;
		synchronized (domain_hash) {
			domain = domain_hash.get(domain_name);
		}
		if(domain == null){
			domain = new Domain();
			synchronized (domain_hash) {
				domain_hash.put(domain_name, domain);
			}
		}
		return domain;
	}
	
	/**
	 * Adds a user to this applications Address Book (basically adds
	 * @param u
	 */
	public static void addInbox(Inbox i){
		Domain domain = getDomain(i.domain());
		domain.addInbox(i);
		synchronized(user_hash){
			user_hash.put(i.call_id, domain);
		}
		
	}
	static public void removeInbox(Inbox i){
		Domain domain = getDomain(i.domain());
		domain.removeInbox(i);
		synchronized(user_hash){
			user_hash.remove(i.call_id);
		}
	}
	/**
	 * Needs to add continuation to 2 places
	 * @param continuation
	 * @param caller_id
	 * @param domain
	 */
	static public void addContinuation(Continuation c, HttpSession session, int timeoutSec){
		Inbox i = (Inbox) session.getAttribute("Inbox");
		Domain domain = getDomain(i.domain());
		domain.addContinuation(c, session, timeoutSec);
	}
	//needs to resume 1 continuation, and remove it from
	//the domain's list of continuations
	static void resumeContinuation(HttpSession session ){
		Inbox i = (Inbox) session.getAttribute("Inbox");
		Domain domain = getDomain(i.domain());
		domain.resumeContinuation(i);
	}
	
	public static void addToOneInbox(Message message){
		Domain d;
		synchronized (user_hash) {
			d = user_hash.get(message.to());
		}
		if(d == null) return;
		d.newMessageOne(message, message.to());
	}
	public static void addToInboxesForDomain(Message message){
		Domain d  = getDomain(message.domainName());
		d.newMessageAll(message);
	}
	public static void banInbox(Message message, boolean ban){
		Domain d  = getDomain(message.domainName());
		logger.info("BLOCKING: "+message.domainName()+": "+ban);
		logger.info("BLOCKING: "+d);
		d.banInbox(message.from, ban);
	}
	
	
}
